package adamCode;

import java.io.IOException;
import java.util.HashMap;
import java.util.Vector;

import javax.jmdns.JmDNS;
import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

public class RemoteApplet extends javax.swing.JApplet {
	// add new service type declaration here
	public static final String SERVICE_TYPE = "_media_service._tcp.local.";
	public static final String SERVICE_TYPE2 = "_screen_service._tcp.local.";
	
	//GUI declarations
	private JButton starterButton;
	private JButton DeviceToggle;
	private JButton playButton;
	private JButton pauseButton;
	private JButton stopButton;
	private JButton returnButton;
	private JButton tempButton;
	private JButton listGetter;
	private JButton refreshButton;
	private JmDNS jmdns = null;
	public String selectedDevice = "command";
	public ServiceEvent Device1 = null;
	public TCPSocketClientremote chatter;
	public Vector<JButton> listy = null;
	public Vector<JButton> DeviceButtonList = null;
	public Vector<ServiceEvent> DeviceList = new Vector<ServiceEvent>();
	public HashMap<String, ServiceEvent> mediaButtons = new HashMap<String, ServiceEvent>();
	public HashMap<String, ServiceEvent> screenButtons = new HashMap<String, ServiceEvent>();
	public ServiceEvent currentScreen = null; //information required to connect to a particular screen
	public ServiceEvent currentMedia = null;
	/**
	 * Auto-generated main method to display this JApplet inside a new JFrame.
	 */
	public static void main(final String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				final JFrame frame = new JFrame();
				final RemoteApplet inst = new RemoteApplet();
				frame.getContentPane().add(inst);
				((JComponent) frame.getContentPane()).setPreferredSize(inst
						.getSize());
				frame.pack();
				frame.setVisible(true);
			}
		});

	}

	public RemoteApplet() {
		super();
		initGUI();
	}

	private void initGUI() {
		try {
			this.setSize(700, 480);
			getContentPane().setLayout(null);
			{
				starterButton = new JButton();
				getContentPane().add(starterButton);
				starterButton.setText("start");
				starterButton.setBounds(12, 12, 64, 23);
				starterButton.addActionListener(new java.awt.event.ActionListener() {
					@Override
					public void actionPerformed(final java.awt.event.ActionEvent e) {
						DeviceButtonList = new Vector<JButton>();
						listy = new Vector<JButton>();
						starterButton.setVisible(false);
						refreshButton.setVisible(true);
						try {
							jmdns = JmDNS.create();
							jmdns.addServiceListener(RemoteApplet.SERVICE_TYPE, new SampleListener());
							jmdns.addServiceListener(RemoteApplet.SERVICE_TYPE2, new SampleListener());
						} catch (final IOException e1) {
							e1.printStackTrace();
						}

					}
				});
			}
			//This button is used to gracefully disconnect the controller
			{
				refreshButton = new JButton();
				getContentPane().add(refreshButton);
				refreshButton.setText("finish");
				refreshButton.setVisible(false);
				refreshButton.setBounds(12, 12, 75, 23);

				refreshButton
				.addActionListener(new java.awt.event.ActionListener() {
					@Override
					public void actionPerformed(
							final java.awt.event.ActionEvent e) {

						refreshButton.setVisible(false);
						//deviceOptionButton.setVisible(false);
						listGetter.setVisible(false);
						clearDeviceList();
						DeviceButtonList = null;
						DeviceList = null;
						clearList();
						listy = null;
						starterButton.setVisible(true);
						jmdns.unregisterAllServices();
						jmdns.close();

					}
				});
			}
			//This button is used to display the list of media in a device //TODO
			{
				listGetter = new JButton();
				getContentPane().add(listGetter);
				listGetter.setText("refresh");
				listGetter.setBounds(340, 221, 100, 23);
				listGetter.setVisible(false);
				listGetter.addActionListener(new java.awt.event.ActionListener() {
					public void actionPerformed(final java.awt.event.ActionEvent e) {
						chatter = new TCPSocketClientremote(Device1.getInfo().getHostAddress(), Device1.getInfo().getPort());
						chatter.sendMessage("list");
						final Vector<String> temp = chatter.movieList;
						System.out.println("list size"+ listy.size());
						if (listy != null) {
							clearList();
						}
						listy = new Vector<JButton>(); // resets the list for updates
						for (int i = 0; i < temp.size(); i++) { //makes a new button with appropriate functionality
							final String tempMovieName = temp.get(i);
							tempButton = new JButton();
							getContentPane().add(tempButton);
							tempButton.setText(tempMovieName);
							tempButton.setBounds(60, 250 + 30 * i, tempMovieName.length() * 10, 20);
							tempButton.addActionListener(new java.awt.event.ActionListener() {
								@Override
								public void actionPerformed(final java.awt.event.ActionEvent e) {
									chatter = new TCPSocketClientremote(Device1.getInfo().getHostAddress(), Device1.getInfo().getPort());
									chatter.sendMessage("play->" + tempMovieName);
									chatter = new TCPSocketClientremote(currentScreen.getInfo().getHostAddress(), currentScreen.getInfo().getPort());
									chatter.sendMessage("play->" + tempMovieName);
									runCheck();
								}
							});
							listy.add(tempButton);

						}
					}
				});
			}
			//Media control buttons. Allows users to send commands to play, pause or stop a media file.
			{
				returnButton = new JButton();
				getContentPane().add(returnButton);
				returnButton.setText("back");
				returnButton.setBounds(76, 306, 80, 60);
				returnButton.setVisible(false);
				returnButton
				.addActionListener(new java.awt.event.ActionListener() {
					@Override
					public void actionPerformed(
							final java.awt.event.ActionEvent e) {
						chatter = new TCPSocketClientremote(Device1
								.getInfo().getHostAddress(), Device1
								.getInfo().getPort());
						chatter.sendMessage("command->back");
						chatter.play_mode = false;
						runCheck();
					}
				});
			}
			{
				stopButton = new JButton();
				getContentPane().add(stopButton);
				stopButton.setText("stop");
				stopButton.setBounds(155, 306, 80, 60);
				stopButton.setVisible(false);
				stopButton
				.addActionListener(new java.awt.event.ActionListener() {
					@Override
					public void actionPerformed(
							final java.awt.event.ActionEvent e) {
						chatter = new TCPSocketClientremote(Device1
								.getInfo().getHostAddress(), Device1
								.getInfo().getPort());
						chatter.sendMessage("command->stop");
					}
				});
			}
			{
				pauseButton = new JButton();
				getContentPane().add(pauseButton);
				pauseButton.setText("pause");
				pauseButton.setBounds(234, 306, 80, 60);
				pauseButton.setVisible(false);
				pauseButton
				.addActionListener(new java.awt.event.ActionListener() {
					@Override
					public void actionPerformed(
							final java.awt.event.ActionEvent e) {
						chatter = new TCPSocketClientremote(Device1
								.getInfo().getHostAddress(), Device1
								.getInfo().getPort());
						chatter.sendMessage("command->pause");
					}
				});
			}
			{
				playButton = new JButton();
				getContentPane().add(playButton);
				playButton.setText("play");
				playButton.setBounds(313, 306, 80, 60);
				playButton.setVisible(false);
				playButton
				.addActionListener(new java.awt.event.ActionListener() {
					@Override
					public void actionPerformed(
							final java.awt.event.ActionEvent e) {
						chatter = new TCPSocketClientremote(Device1
								.getInfo().getHostAddress(), Device1
								.getInfo().getPort());
						chatter.sendMessage("command->play");
					}
				});
			}

		} catch (final Exception e) {
			e.printStackTrace();
		}
	}

	//Refresh the list of media and screen buttons. Used to add or remove new devices
	public void refresh(){		
		clearDeviceList();
		clearList();
		final Object[] mediaKeys = mediaButtons.keySet().toArray();
		final Object[] mediaValues = mediaButtons.values().toArray();
		final Object[] screenKeys = screenButtons.keySet().toArray();
		final Object[] screenValues = screenButtons.values().toArray();
		//get media devices a button
		for (int i = 0; i < mediaButtons.size(); i++) {
			DeviceToggle = new JButton();
			getContentPane().add(DeviceToggle);
			DeviceToggle.setText(mediaKeys[i].toString());
			DeviceToggle.setBounds(400, 20 + i * 30, 150, 23);
			DeviceToggle.addActionListener(new java.awt.event.ActionListener() {
				@Override
				public void actionPerformed(final java.awt.event.ActionEvent e) {
					Device1 = mediaButtons.get(((JButton) e.getSource()).getText());
					selectedDevice = Device1.getName();
					if(currentScreen == null){
						JOptionPane.showMessageDialog(null, "Please choose a screen first");
					} else{
						currentMedia = Device1;
						listGetter();
					}
				}
			});
			DeviceButtonList.add(DeviceToggle);
		}
		//get screens a button
		for (int i = 0; i < screenButtons.size(); i++) {
			JButton DeviceToggle2 = new JButton();
			getContentPane().add(DeviceToggle2);
			DeviceToggle2.setText(screenKeys[i].toString());
			DeviceToggle2.setBounds(236, 20 + i * 30, 150, 23);
			DeviceToggle2.addActionListener(new java.awt.event.ActionListener() {
				@Override
				public void actionPerformed(final java.awt.event.ActionEvent e) {
					currentScreen = screenButtons.get(((JButton) e.getSource()).getText());
				}
			});
			DeviceButtonList.add(DeviceToggle2);
		}
	}
	
	// test method to see if the play_mode is now true
	public void runCheck() {

		for (final JButton temp : listy) {
			temp.setVisible(!chatter.play_mode);
		}
		listGetter.setVisible(!chatter.play_mode);
		returnButton.setVisible(chatter.play_mode);
		stopButton.setVisible(chatter.play_mode);
		pauseButton.setVisible(chatter.play_mode);
		playButton.setVisible(chatter.play_mode);
	}

	//clear list of movies on the controller
	public void clearList() {
		if(listy!=null){
			for (final JButton temp : listy) {
				temp.setVisible(false);
			}
			listy.clear();
		}
	}

	//clear the list of all devices on the controller. used for refresh.
	public void clearDeviceList() {
		if(DeviceButtonList != null){
			for (final JButton temp : DeviceButtonList) {
				temp.setVisible(false);
			}
		}
	}
	
	//Automatically return the list of media on a device //TODO
	public void listGetter(){
		chatter = new TCPSocketClientremote(Device1.getInfo().getHostAddress(), Device1
			.getInfo().getPort());
		if(chatter.sendMessage("list")==true){
		final Vector<String> temp = chatter.movieList;
		if (listy != null) {
			clearList();
		}	
		listy = new Vector<JButton>();
		for (int i = 0; i < temp.size(); i++) {
			final String tempMovieName = temp.get(i);
			tempButton = new JButton();
			getContentPane().add(tempButton);
			tempButton.setText(tempMovieName);
			tempButton.setBounds(60, 250 + 30 * i, tempMovieName.length() * 10, 20);
			tempButton.addActionListener(new java.awt.event.ActionListener() {
				@Override
				public void actionPerformed(final java.awt.event.ActionEvent e) {
					chatter = new TCPSocketClientremote(Device1.getInfo().getHostAddress(),
						Device1.getInfo().getPort());
					chatter.sendMessage("play->" + tempMovieName);
					chatter = new TCPSocketClientremote(currentScreen.getInfo().getHostAddress(),
						currentScreen.getInfo().getPort());
					chatter.sendMessage("play->" + tempMovieName);
					runCheck();
				}
			});
			listy.add(tempButton);
		}
		}else{
			mediaButtons.remove(currentMedia.getName());
			System.out.println(mediaButtons);
			refresh();
		}
	}

	// set of controls for the jmDNS
	class SampleListener implements ServiceListener {
		@Override
		public void serviceAdded(final ServiceEvent event) {
				event.getDNS().requestServiceInfo(event.getType(),
						event.getName(), 0);
		}

		@Override
		public void serviceRemoved(final ServiceEvent event) {
			//handle gracefully removes media
			if (event.getType().equals(RemoteApplet.SERVICE_TYPE)) {
				mediaButtons.remove(event.getInfo().getName());
			}
			//handle gracefully removed screen
			if (event.getType().equals(RemoteApplet.SERVICE_TYPE2)) {
				if(currentScreen == event){
					currentScreen = null;
					System.out.println("TEST");
				}
				screenButtons.remove(event.getInfo().getName());
			}
			refresh();
		}

		@Override
		public void serviceResolved(final ServiceEvent event) {
			//if media add to media hashset
			if (event.getType().equals(RemoteApplet.SERVICE_TYPE)) {
				DeviceList.addElement(event);
				final ServiceEvent temp = DeviceList.lastElement();
				mediaButtons.put(event.getInfo().getName(), temp);
			}
			//if screen add to screen hashset
			if (event.getType().equals(RemoteApplet.SERVICE_TYPE2)) {
				DeviceList.addElement(event);
				final ServiceEvent temp = DeviceList.lastElement();
				screenButtons.put(event.getInfo().getName(), temp);
			}
			refresh(); //refresh list of devices on the controller
			
		}
	}

}
